//
// TCP Sokect 管理
// Created by kenny on 25-10-16.
//
#include "mcp_tcp.h"
#include "mcp_logger.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef _WIN32
    #include <ws2tcpip.h>
    #include <io.h>
    #if defined(_MSC_VER)
       #pragma comment(lib, "ws2_32.lib")
    #endif
#else
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #include <pthread.h>

    #include <fcntl.h>
    #include <errno.h>
    #include <poll.h>
#endif

// 内部函数声明
#ifdef _WIN32
static DWORD WINAPI recv_thread_func(LPVOID param);
static DWORD WINAPI send_thread_func(LPVOID param);
#else
static void* recv_thread_func(void* param);
static void* send_thread_func(void* param);
#endif

// 发送队列节点
typedef struct send_queue_node {
    uint8_t* data;
    uint16_t length;
    struct send_queue_node* next;
} send_queue_node_t;

// 发送队列
typedef struct {
    send_queue_node_t* head;
    send_queue_node_t* tail;
#ifdef _WIN32
    CRITICAL_SECTION lock;
    CONDITION_VARIABLE cond;
#else
    pthread_mutex_t lock;
    pthread_cond_t cond;
#endif
    bool has_data;
} send_queue_t;

static send_queue_t send_queue;

// 初始化发送队列
static void send_queue_init() {
    send_queue.head = NULL;
    send_queue.tail = NULL;
    send_queue.has_data = false;
#ifdef _WIN32
    InitializeCriticalSection(&send_queue.lock);
    InitializeConditionVariable(&send_queue.cond);
#else
    pthread_mutex_init(&send_queue.lock, NULL);
    pthread_cond_init(&send_queue.cond, NULL);
#endif
}

/**
 * 添加到发送队列
 * @param data 数据
 * @param length  数据长度
 */
static void send_queue_push(const uint8_t* data, uint16_t length) {
    send_queue_node_t* node = (send_queue_node_t*)malloc(sizeof(send_queue_node_t));
    node->data = (uint8_t*)malloc(length);
    memcpy(node->data, data, length);
    node->length = length;
    node->next = NULL;

#ifdef _WIN32
    EnterCriticalSection(&send_queue.lock);
#else
    pthread_mutex_lock(&send_queue.lock);
#endif

    if (send_queue.tail) {
        send_queue.tail->next = node;
    } else {
        send_queue.head = node;
    }
    send_queue.tail = node;
    send_queue.has_data = true;

#ifdef _WIN32
    LeaveCriticalSection(&send_queue.lock);
    WakeConditionVariable(&send_queue.cond);
#else
    pthread_mutex_unlock(&send_queue.lock);
    pthread_cond_signal(&send_queue.cond);
#endif
}

/**
 * 取得队列的第一个数据
 * @return
 */
static send_queue_node_t* send_queue_pop() {
#ifdef _WIN32
    EnterCriticalSection(&send_queue.lock);

    while (!send_queue.has_data) {
        SleepConditionVariableCS(&send_queue.cond, &send_queue.lock, INFINITE);
    }

    send_queue_node_t* node = send_queue.head;
    if (node) {
        send_queue.head = node->next;
        if (!send_queue.head) {
            send_queue.tail = NULL;
        }
        send_queue.has_data = (send_queue.head != NULL);
    }

    LeaveCriticalSection(&send_queue.lock);
#else
    pthread_mutex_lock(&send_queue.lock);

    while (!send_queue.has_data) {
        pthread_cond_wait(&send_queue.cond, &send_queue.lock);
    }

    send_queue_node_t* node = send_queue.head;
    if (node) {
        send_queue.head = node->next;
        if (!send_queue.head) {
            send_queue.tail = NULL;
        }
        send_queue.has_data = (send_queue.head != NULL);
    }

    pthread_mutex_unlock(&send_queue.lock);
#endif
    return node;
}

/**
 * 删除发送队列中的所有数据
 */
static void send_queue_clear() {
#ifdef _WIN32
    EnterCriticalSection(&send_queue.lock);
#else
    pthread_mutex_lock(&send_queue.lock);
#endif

    send_queue_node_t* current = send_queue.head;
    while (current) {
        send_queue_node_t* next = current->next;
        free(current->data);
        free(current);
        current = next;
    }
    send_queue.head = NULL;
    send_queue.tail = NULL;
    send_queue.has_data = false;

#ifdef _WIN32
    LeaveCriticalSection(&send_queue.lock);
#else
    pthread_mutex_unlock(&send_queue.lock);
#endif
}

/**
 * 清空发送队列
 */
static void send_queue_cleanup() {
    send_queue_clear();
#ifdef _WIN32
    DeleteCriticalSection(&send_queue.lock);
#else
    pthread_mutex_destroy(&send_queue.lock);
    pthread_cond_destroy(&send_queue.cond);
#endif
}

/**
 * TCP 连接初始化
 * @param manager
 * @param ip
 * @param port
 * @param recv_cb
 * @param status_cb
 * @return
 */
int mcp_tcp_init(mcp_tcp_t* manager,
                            const char* ip, int port,
                            recv_callback_t recv_cb,
                            connection_status_callback_t status_cb) {
    if (!manager || !ip || !recv_cb) {
        return -1;
    }

    memset(manager, 0, sizeof(mcp_tcp_t));

    strncpy(manager->server_ip, ip, sizeof(manager->server_ip) - 1);
    manager->server_port = port;
    manager->recv_callback = recv_cb;
    manager->status_callback = status_cb;

    manager->socket_fd = INVALID_SOCKET;
    manager->is_connected = false;
    manager->should_reconnect = true;
    manager->manual_close = false;
    manager->running = true; // 表示已开始运行

    // 设置连接超时（默认10秒）
    manager->connect_timeout_sec = 10;

    // 配置重连策略
    manager->reconnect_config.max_retries = 5;
    manager->reconnect_config.retry_delays[0] = 0;    // 第1次：立即重连
    manager->reconnect_config.retry_delays[1] = 30;   // 第2次：30秒后重连
    manager->reconnect_config.retry_delays[2] = 60;   // 第3次：1分钟后重连
    manager->reconnect_config.retry_delays[3] = 120;  // 第4次：2分钟后重连
    manager->reconnect_config.retry_delays[4] = 300;  // 第5次：5分钟后重连
    manager->reconnect_config.current_retry_count = 0;

#ifdef _WIN32
    InitializeCriticalSection(&manager->send_lock);
#else
    pthread_mutex_init(&manager->send_lock, NULL);
#endif

    // 初始化Winsock（Windows平台）
#ifdef _WIN32
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
        LOG_ERROR("WSAStartup failed");
        return -1;
    }
#endif

    send_queue_init();
    return 0;
}


/**
 * 偿试连接 socket， 非阻塞模式
 * @param manager
 * @return
 */
static int attempt_connection(mcp_tcp_t* manager) {
    struct sockaddr_in server_addr;
    int result;

    // 创建socket
    manager->socket_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (manager->socket_fd == INVALID_SOCKET) {
        LOG_ERROR("Socket creation failed");
        return -1;
    }

    // 设置为非阻塞模式
#ifdef _WIN32
    u_long mode = 1; // 1 表示非阻塞
    if (ioctlsocket(manager->socket_fd, FIONBIO, &mode) != 0) {
        LOG_ERROR("Failed to set non-blocking mode");
        closesocket(manager->socket_fd);
        manager->socket_fd = INVALID_SOCKET;
        return -1;
    }
#else
    int flags = fcntl(manager->socket_fd, F_GETFL, 0);
    if (fcntl(manager->socket_fd, F_SETFL, flags | O_NONBLOCK) == -1) {
        LOG_ERROR("Failed to set non-blocking mode");
        close(manager->socket_fd);
        manager->socket_fd = INVALID_SOCKET;
        return -1;
    }
#endif

    // 设置服务器地址
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(manager->server_port);
    server_addr.sin_addr.s_addr = inet_addr(manager->server_ip);

    // 非阻塞连接
    result = connect(manager->socket_fd, (struct sockaddr*)&server_addr, sizeof(server_addr));

    if (result == 0) {
        // 连接立即成功（罕见情况）
        LOG_INFO("Connection established immediately");
        goto connection_success;
    }
    else if (result == SOCKET_ERROR) {
#ifdef _WIN32
        if (WSAGetLastError() == WSAEWOULDBLOCK) {
#else
        if (errno == EINPROGRESS) {
#endif
            // 连接正在进行中，这是正常情况
            LOG_DEBUG("Connection in progress, waiting for completion...");

            // 使用 select 等待连接完成（带超时）
            fd_set writefds, exceptfds;
            struct timeval timeout;
            int select_result;

            FD_ZERO(&writefds);
            FD_ZERO(&exceptfds);
            FD_SET(manager->socket_fd, &writefds);
            FD_SET(manager->socket_fd, &exceptfds);

            timeout.tv_sec = manager->connect_timeout_sec;
            timeout.tv_usec = 0;

            select_result = select((int)(manager->socket_fd + 1), NULL, &writefds, &exceptfds, &timeout);

            if (select_result == 0) {
                LOG_ERROR("Connection timeout to %s:%d after %d seconds",manager->server_ip, manager->server_port, manager->connect_timeout_sec);
                goto connection_failed;
            } else if (select_result == SOCKET_ERROR) {
                LOG_ERROR("Select error during connection");
                goto connection_failed;
            }

            // 检查连接是否成功
            if (FD_ISSET(manager->socket_fd, &exceptfds)) {
                // 获取具体的socket错误
                int socket_error = 0;
                socklen_t len = sizeof(socket_error);
                getsockopt(manager->socket_fd, SOL_SOCKET, SO_ERROR, (char*)&socket_error, &len);

                if (socket_error != 0) {
                    LOG_ERROR("Connection failed: error %d", socket_error);
                } else {
                    LOG_ERROR("Connection failed with exception");
                }
                goto connection_failed;
            }

            // 连接成功！
            LOG_DEBUG("Connection completed successfully via select");
            goto connection_success;
        }
        else {
            // 真正的立即失败
#ifdef _WIN32
            int error = WSAGetLastError();
#else
            int error = errno;
#endif
            LOG_ERROR("Connection failed immediately: error %d", error);
            goto connection_failed;
        }
    }

connection_success:
    // 连接成功，设置回阻塞模式
    // ... 原有代码不变
    manager->is_connected = true;

    manager->reconnect_config.current_retry_count = 0;
    LOG_INFO("Connected to server %s:%d", manager->server_ip, manager->server_port);

    if (manager->status_callback) {
        manager->status_callback(true, "Connection success");
    }
    return 0;

connection_failed:
#ifdef _WIN32
    closesocket(manager->socket_fd);
#else
    close(manager->socket_fd);
#endif
    manager->socket_fd = INVALID_SOCKET;

    manager->is_connected = false;

    if (manager->status_callback) {
        manager->status_callback(false, "Connection failure");
    }

    return -1;
}

/**
 * 启动重连机制
 * @param manager
 */
static void handle_reconnection(mcp_tcp_t* manager) {
    if (manager->manual_close || !manager->should_reconnect) {
        return;
    }

    while (manager->reconnect_config.current_retry_count < manager->reconnect_config.max_retries) {
        int delay = manager->reconnect_config.retry_delays[manager->reconnect_config.current_retry_count];

        if (delay > 0) {
            LOG_INFO("Reconnecting in %d seconds (attempt %d/%d)",
                     delay, manager->reconnect_config.current_retry_count + 1,
                     manager->reconnect_config.max_retries);

            // 睡眠指定时间
#ifdef _WIN32
            Sleep(delay * 1000);
#else
            sleep(delay);
#endif
        }

        LOG_INFO("Attempting to reconnect... (%d/%d)",
                 manager->reconnect_config.current_retry_count + 1,
                 manager->reconnect_config.max_retries);

        if (attempt_connection(manager) == 0) {
            // 重新启动接收线程
#ifdef _WIN32
            manager->recv_thread = CreateThread(NULL, 0, recv_thread_func, manager, 0, NULL);
            if (manager->recv_thread == NULL) {
                LOG_ERROR("Failed to create receive thread after reconnection");
                manager->is_connected = false;
                continue;
            }
#else
            if (pthread_create(&manager->recv_thread, NULL, recv_thread_func_linux, manager) != 0) {
                LOG_ERROR("Failed to create receive thread after reconnection");
                manager->is_connected = false;
                continue;
            }
#endif
            return; // 重连成功
        }

        manager->reconnect_config.current_retry_count++;
    }

    // 重连失败
    LOG_ERROR("Failed to reconnect after %d attempts", manager->reconnect_config.max_retries);
    if (manager->status_callback) {
        manager->status_callback(false, "Reconnection failed");
    }
}

/**
 * 数据包接收处理
 * param mcp_tcp_t
 */
#ifdef _WIN32
static DWORD WINAPI recv_thread_func_back(LPVOID param) {
#else
static void* recv_thread_func(void* param) {
#endif
    mcp_tcp_t* manager = (mcp_tcp_t*)param;
    uint8_t buffer[2024];

    // 设置接收超时
#ifdef _WIN32
    DWORD timeout = 5000; // 5秒超时
    setsockopt(manager->socket_fd, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));
#else
    struct timeval timeout;
    timeout.tv_sec = 5;
    timeout.tv_usec = 0;
    setsockopt(manager->socket_fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
#endif

    while (manager->running && manager->is_connected) {
        int received;
#ifdef _WIN32
        received = recv(manager->socket_fd, (char*)buffer, sizeof(buffer), 0);
#else
        received = recv(manager->socket_fd, buffer, sizeof(buffer), 0);
#endif

        if (received == SOCKET_ERROR) {
#ifdef _WIN32
            if (WSAGetLastError() == WSAETIMEDOUT) {
                continue; // 超时，继续接收
            }
#endif
            LOG_ERROR("Receive failed, connection lost");
            manager->is_connected = false;
            break;
        } else if (received == 0) {
            LOG_INFO("Server disconnected");
            manager->is_connected = false;
            break;
        }

        if (received > 0 && manager->recv_callback) {
            manager->recv_callback(buffer, received);
        }
    }

    // 连接断开，处理重连
    if (manager->running && !manager->is_connected ) {
        if (manager->status_callback) {
            manager->status_callback(false, "Connection lost");
        }
        if (!manager->manual_close) {
            handle_reconnection(manager);
        }
    }

#ifdef _WIN32
    return 0;
#else
    return NULL;
#endif
}

/**
 * 数据包接收处理 - 使用poll事件驱动（Linux/Unix）
 */
#ifdef _WIN32
#else
static void* recv_thread_func_linux(void* param) {
    mcp_tcp_t* manager = (mcp_tcp_t*)param;
    uint8_t buffer[2024];
    struct pollfd fds[1];

    // 设置为非阻塞模式
    int flags = fcntl(manager->socket_fd, F_GETFL, 0);
    fcntl(manager->socket_fd, F_SETFL, flags | O_NONBLOCK);

    fds[0].fd = manager->socket_fd;
    fds[0].events = POLLIN;  // 监听可读事件
    fds[0].revents = 0;

    while (manager->running && manager->is_connected) {
        int poll_result = poll(fds, 1, 1000); // 1秒超时

        if (poll_result == -1) {
            LOG_ERROR("Poll error in receive thread");
            manager->is_connected = false;
            break;
        } else if (poll_result == 0) {
            // 超时，继续循环
            continue;
        }

        // 检查是否有数据可读
        if (fds[0].revents & POLLIN) {
            int received = recv(manager->socket_fd, buffer, sizeof(buffer), 0);

            if (received == -1) {
                if (errno == EAGAIN || errno == EWOULDBLOCK) {
                    continue;
                }
                LOG_ERROR("Receive failed, connection lost");
                manager->is_connected = false;
                break;
            } else if (received == 0) {
                LOG_INFO("Server disconnected gracefully");
                manager->is_connected = false;
                break;
            } else if (received > 0) {
                if (manager->recv_callback) {
                    manager->recv_callback(buffer, received);
                }
            }
        }

        // 检查连接错误
        if (fds[0].revents & (POLLERR | POLLHUP | POLLNVAL)) {
            LOG_ERROR("Socket error detected in poll");
            manager->is_connected = false;
            break;
        }
    }

    // 连接断开处理（同上）
    // ...
    return NULL;
}
#endif
/**
 * 非阻塞数据包接收处理 - 混合方案，兼顾效率和兼容性
 */
#ifdef _WIN32
static DWORD WINAPI recv_thread_func(LPVOID param) {
#else
static void* recv_thread_func(void* param) {
#endif
    mcp_tcp_t* manager = (mcp_tcp_t*)param;
    uint8_t buffer[2024];

    // 设置socket为非阻塞
#ifdef _WIN32
    u_long mode = 1;
    ioctlsocket(manager->socket_fd, FIONBIO, &mode);
#else
    int flags = fcntl(manager->socket_fd, F_GETFL, 0);
    fcntl(manager->socket_fd, F_SETFL, flags | O_NONBLOCK);
#endif

    while (manager->running && manager->is_connected) {
        int select_result;

#ifdef _WIN32
        fd_set readfds;
        struct timeval timeout;

        FD_ZERO(&readfds);
        FD_SET(manager->socket_fd, &readfds);
        timeout.tv_sec = 0;  // 不阻塞，立即返回
        timeout.tv_usec = 100000; // 100ms

        select_result = select((int)(manager->socket_fd + 1), &readfds, NULL, NULL, &timeout);
#else
        struct pollfd fds[1];
        fds[0].fd = manager->socket_fd;
        fds[0].events = POLLIN;
        fds[0].revents = 0;

        select_result = poll(fds, 1, 100); // 100ms超时
#endif

        if (select_result == SOCKET_ERROR) {
            LOG_ERROR("Select/poll error in receive thread");
            manager->is_connected = false;
            break;
        } else if (select_result == 0) {
            // 短暂休眠，避免CPU占用过高
#ifdef _WIN32
            Sleep(10); // 10ms
#else
            usleep(10000); // 10ms
#endif
            continue;
        }

        // 有数据可读
        int received;
#ifdef _WIN32
        if (FD_ISSET(manager->socket_fd, &readfds)) {
            received = recv(manager->socket_fd, (char*)buffer, sizeof(buffer), 0);
#else
        if (fds[0].revents & POLLIN) {
            received = recv(manager->socket_fd, buffer, sizeof(buffer), 0);
#endif
            if (received == SOCKET_ERROR) {
#ifdef _WIN32
                if (WSAGetLastError() == WSAEWOULDBLOCK) continue;
#else
                if (errno == EAGAIN || errno == EWOULDBLOCK) continue;
#endif
                LOG_ERROR("Receive failed");
                manager->is_connected = false;
                break;
            } else if (received == 0) {
                LOG_INFO("Server disconnected");
                manager->is_connected = false;
                break;
            } else if (received > 0) {
                if (manager->recv_callback) {
                    manager->recv_callback(buffer, received);
                }
            }
        }
    }

    // 连接断开处理
    if (manager->running && !manager->is_connected) {
        if (manager->status_callback) {
            manager->status_callback(false, "Connection lost");
        }
        if (!manager->manual_close) {
            handle_reconnection(manager);
        }
    }

#ifdef _WIN32
    return 0;
#else
    return NULL;
#endif
}
/**
 * 数据发送线程
 */
#ifdef _WIN32
static DWORD WINAPI send_thread_func(LPVOID param) {
#else
static void* send_thread_func(void* param) {
#endif
    mcp_tcp_t* manager = (mcp_tcp_t*)param;

    while (manager->running) {
        send_queue_node_t* node = send_queue_pop();
        if (!node) continue;

        if (manager->is_connected) {
            int sent;
#ifdef _WIN32
            sent = send(manager->socket_fd, (char*)node->data, node->length, 0);
#else
            sent = send(manager->socket_fd, node->data, node->length, 0);
#endif

            if (sent == SOCKET_ERROR) {
                LOG_ERROR("Send failed");
                // 发送失败，可能需要触发重连
                if (!manager->manual_close) {
                    manager->is_connected = false;
#ifdef _WIN32
                    closesocket(manager->socket_fd);
#else
                    close(manager->socket_fd);
#endif
                    manager->socket_fd = INVALID_SOCKET;
                }
            } else {
                LOG_DEBUG("Sent %d bytes to server", sent);
            }
        } else {
            LOG_WARN("Cannot send data, socket not connected");
        }

        free(node->data);
        free(node);
    }

#ifdef _WIN32
    return 0;
#else
    return NULL;
#endif
}

/**
 * 启动通信线程，包括发送线程和接收线程的启动
 * @param manager
 * @return
 */
static int start_communication_threads(mcp_tcp_t* manager) {
    // 启动接收线程
#ifdef _WIN32
    manager->recv_thread = CreateThread(NULL, 0, recv_thread_func, manager, 0, NULL);
    if (manager->recv_thread == NULL) {
        LOG_ERROR("Failed to create receive thread");
        return -1;
    }
#else
    if (pthread_create(&manager->recv_thread, NULL, recv_thread_func, manager) != 0) {
        LOG_ERROR("Failed to create receive thread");
        return -1;
    }
#endif

    // 启动发送线程
#ifdef _WIN32
    manager->send_thread = CreateThread(NULL, 0, send_thread_func, manager, 0, NULL);
    if (manager->send_thread == NULL) {
        LOG_ERROR("Failed to create send thread");
        TerminateThread(manager->recv_thread, 0);
        return -1;
    }
#else
    if (pthread_create(&manager->send_thread, NULL, send_thread_func, manager) != 0) {
        LOG_ERROR("Failed to create send thread");
        pthread_cancel(manager->recv_thread);
        return -1;
    }
#endif

    return 0;
}

/**
 *  启动连接线程，在一个新的线程启用，这个是为了防止当服务器阻塞或网络抖动造成的连接延时
 */
#ifdef _WIN32
static DWORD WINAPI connect_thread_func(LPVOID param) {
#else
static void* connect_thread_func(void* param) {
#endif
    mcp_tcp_t* manager = (mcp_tcp_t*)param;

    // 开始连接
    if (attempt_connection(manager) == 0) {
        // 连接成功，启动接收和发送线程
        start_communication_threads(manager);
    } else {
        // 连接失败，处理重连
        handle_reconnection(manager);
    }
#ifdef _WIN32
    return 0;
#else
    return NULL;
#endif
}

/**
 * TCP 连接管理
 * @param manager
 * @return
 */
int mcp_tcp_connect(mcp_tcp_t* manager) {
    if (!manager) return -1;

    manager->manual_close = false;
    // manager->running = true;

    // 在单独线程中执行连接，避免阻塞调用者, 在connect_thread_func 调用 attempt_connection
#ifdef _WIN32
    HANDLE connect_thread = CreateThread(NULL, 0, connect_thread_func, manager, 0, NULL);
    if (connect_thread == NULL) {
        LOG_ERROR("Failed to create connect thread");
        return -1;
    }
    CloseHandle(connect_thread); // 我们不等待这个线程结束
#else
    pthread_t connect_thread;
    if (pthread_create(&connect_thread, NULL, connect_thread_func, manager) != 0) {
        LOG_ERROR("Failed to create connect thread");
        return -1;
    }
    pthread_detach(connect_thread); // 分离线程，不等待它结束
#endif
    return 0;
}

int mcp_tcp_send(mcp_tcp_t* manager, const uint8_t* data, uint16_t length) {
    if (!manager || !data || length == 0) {
        return -1;
    }

    if (!manager->is_connected) {
        LOG_WARN("Cannot send data, socket not connected");
        return -1;
    }

    send_queue_push(data, length);
    return 0;
}

int mcp_tcp_close(mcp_tcp_t* manager) {
    if (!manager) return -1;

    manager->manual_close = true;
    manager->should_reconnect = false;
    manager->running = false;
    manager->is_connected = false;

    // 唤醒发送线程使其退出
    send_queue_push(NULL, 0);

    if (manager->socket_fd != INVALID_SOCKET) {
#ifdef _WIN32
        closesocket(manager->socket_fd);
#else
        close(manager->socket_fd);
#endif
        manager->socket_fd = INVALID_SOCKET;
    }

    // 等待线程结束
#ifdef _WIN32
    if (manager->recv_thread) {
        WaitForSingleObject(manager->recv_thread, INFINITE);
        CloseHandle(manager->recv_thread);
    }
    if (manager->send_thread) {
        WaitForSingleObject(manager->send_thread, INFINITE);
        CloseHandle(manager->send_thread);
    }
    DeleteCriticalSection(&manager->send_lock);
#else
    if (manager->recv_thread) {
        pthread_join(manager->recv_thread, NULL);
    }
    if (manager->send_thread) {
        pthread_join(manager->send_thread, NULL);
    }
    pthread_mutex_destroy(&manager->send_lock);
#endif

    if (manager->status_callback) {
        manager->status_callback(false, "Manually closed");
    }

    return 0;
}

bool mcp_tcp_is_connected(mcp_tcp_t* manager) {
    if (manager == NULL) {
        return false;
    }
    return manager->is_connected;
}

void mcp_tcp_cleanup(mcp_tcp_t* manager) {
    if (!manager) return;

    mcp_tcp_close(manager);
    send_queue_cleanup();

#ifdef _WIN32
    WSACleanup();
#endif
}